package com.google.code.jtasks.model;

import java.net.URL;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.joda.time.Duration;

/**
 * A mock {@link IMappedTask} implementation that can be used in tests.
 */
public final class MockMappedTask implements IMappedTask
{
	private static final long serialVersionUID = 7116936614892401384L;

	private final Set<TaskPropertyValue<IMappedTask>> fieldValues;

	/**
	 * Constructs a new {@link MockMappedTask} instance with the specified {@link TaskPropertyValue}s.
	 * 
	 * @param fieldValues
	 *            the {@link TaskPropertyValue}s to populate the {@link MockMappedTask} with
	 */
	public MockMappedTask(TaskPropertyValue<IMappedTask>... fieldValues)
	{
		this.fieldValues = new HashSet<TaskPropertyValue<IMappedTask>>();
		for (TaskPropertyValue<IMappedTask> fieldValue : fieldValues)
			this.fieldValues.add(fieldValue);
	}

	/**
	 * Returns the value of the specified {@link TaskField}, or <code>null</code> if no such {@link TaskField}
	 * is found.
	 * 
	 * @param field
	 *            the {@link TaskField} to get the {@link TaskPropertyValue} of
	 * @return the value of the specified {@link TaskField}, or <code>null</code> if no such {@link TaskField}
	 *         is found
	 */
	private Object findField(TaskField field)
	{
		for (TaskPropertyValue<?> fieldValue : fieldValues)
			if (fieldValue.getProperty().equals(field))
				return fieldValue.getValue();

		return null;
	}

	/**
	 * Returns the {@link TaskPropertyValue}s contained in this {@link MockMappedTask}.
	 * 
	 * @return the {@link TaskPropertyValue}s contained in this {@link MockMappedTask}
	 */
	public Set<TaskPropertyValue<IMappedTask>> getFieldValues()
	{
		return Collections.unmodifiableSet(fieldValues);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getId()
	 */
	@Override
	public TaskId getId()
	{
		return (TaskId) findField(TaskField.ID);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getUrl()
	 */
	@Override
	public URL getUrl()
	{
		return (URL) findField(TaskField.URL);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getSummary()
	 */
	@Override
	public String getSummary()
	{
		return (String) findField(TaskField.SUMMARY);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getOwner()
	 */
	@Override
	public String getOwner()
	{
		return (String) findField(TaskField.OWNER);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getResolution()
	 */
	@Override
	public Resolution getResolution()
	{
		return (Resolution) findField(TaskField.RESOLUTION);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getPriority()
	 */
	@Override
	public Priority getPriority()
	{
		return (Priority) findField(TaskField.PRIORITY);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getProduct()
	 */
	@Override
	public String getProduct()
	{
		return (String) findField(TaskField.PRODUCT);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getComponent()
	 */
	@Override
	public String getComponent()
	{
		return (String) findField(TaskField.COMPONENT);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getTotalWorkEstimate()
	 */
	@Override
	public Duration getTotalWorkEstimate()
	{
		return (Duration) findField(TaskField.TOTAL_WORK_ESTIMATE);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getTimeWorked()
	 */
	@Override
	public Duration getTimeWorked()
	{
		return (Duration) findField(TaskField.TIME_WORKED);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getTags()
	 */
	@SuppressWarnings("unchecked")
	@Override
	public Set<String> getTags()
	{
		return (Set<String>) findField(TaskField.TAGS);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getComments()
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<ITaskComment> getComments()
	{
		return (List<ITaskComment>) findField(TaskField.COMMENTS);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getWorkEntries()
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<ITaskWorkEntry> getWorkEntries()
	{
		return (List<ITaskWorkEntry>) findField(TaskField.WORK_ENTRIES);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getBlocks()
	 */
	@SuppressWarnings("unchecked")
	@Override
	public Set<TaskRelationship> getBlocks()
	{
		return (Set<TaskRelationship>) findField(TaskField.BLOCKS);
	}

	/**
	 * @see com.google.code.jtasks.model.IMappedTask#getDependsOn()
	 */
	@SuppressWarnings("unchecked")
	@Override
	public Set<TaskRelationship> getDependsOn()
	{
		return (Set<TaskRelationship>) findField(TaskField.DEPENDS_ON);
	}
}
